﻿using System.Collections.Generic;
using System.Linq;
using KTOP.Core.Extensions;
using KTOP.Homeworks.Hw5.Logics.CrossMatrix;


namespace KTOP.Homeworks.Hw5.Logics.Psi
{
    internal class PsiCalculator
    {
        public Psi PetuchovAlgorithm(Gsh gsh)
        {
            var psi = new Psi();

            for (var i = 0; i < gsh.GshMatrix.Count; i++)
            {
                var m = new int[gsh.GshMatrix.Count];
                var mset = new List<int>();

                PetuchovAlgorithmIteration(gsh, i, m, mset, psi);
            }

            return psi;
        }

        private static void PetuchovAlgorithmIteration(Gsh gsh, int add, int[] m, ICollection<int> mSet, Psi psi)
        {
            mSet.Add(add);
            m = m.OrWith(gsh.GshMatrix[add])
                .ToArray();

            if (IsFull(m))
            {
                psi.Add(mSet);
                return;
            }

            //рекурсивный поиск следующего
            for (var j = (add + 1); j < m.Length; j++)
            {
                if (m[j] == 0)
                {
                    PetuchovAlgorithmIteration(gsh, j, m.Copy(), new List<int>(mSet), psi);
                }
            }
        }

        private static bool IsFull(IEnumerable<int> ie)
        {
            return ie.All(e => e != 0);
        }


        public static Psi Calculate(Gsh gsh)
        {
            return new PsiCalculator().PetuchovAlgorithm(gsh);
        }

    }
}
